package pATT.DataSetsGenerator.dataSetsGenerator.converter.implement;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import pATT.BasicAlgorithm.classifiers.bayes.bayesNet.BIFReader;
import pATT.core.Attribute;
import pATT.core.Instances;
import pATT.core.Chooser.ImageFilter;
import pATT.logger.Message;




public class XMLBayesConverter extends Converter{
	private static final String barra = "\\";
//	private static final String aux = "''";
	
	Instances instances = null;
	
	public XMLBayesConverter(){
		
		
	}
//	public String convert() throws Exception {
//		File dir = new File(".");
//
//
//		File[] cont = dir.listFiles();
////		int MAX = cont.length;
//		for (int i = 0; i < cont.length; i++) {
//			String tmp = cont[i].getName();
//			JOptionPane.showMessageDialog(null,
//					tmp,
//					Message.ERROR_LOADED_CONVERTER_TITLE,
//					JOptionPane.ERROR_MESSAGE);
//
//			if(tmp.equals("PATT.jar")){
//				JarFile jar = new JarFile(cont[i]);
//				Enumeration files = jar.entries();
//				while (files.hasMoreElements()) {
//					JarEntry f = (JarEntry) files.nextElement();
//					if(f.getName().endsWith(".xml")){
//					JOptionPane.showMessageDialog(null,
//							f+" - "+f.getSize(),
//							Message.ERROR_LOADED_CONVERTER_TITLE,
//							JOptionPane.ERROR_MESSAGE);
//					}
//				}
//					
//				}
//
//
////				aa = new File(cont[i].getAbsolutePath()+File.separator+"SAVER"+File.separator+"xml"+File.separator+"bayesNetXML.xml");
//			}
//		
//return "";
//		
//	}
	/**
	 * Convierte de XML a arff
	 * @throws Exception 
	 * 
	 * */
	@Override
	public String convert() throws Exception {
		String stringArff = "";
	


		File net = new File(Message.PATH_NET_BAYES_DEFAULT);
		
		instances = getRelations(net);
		relationName = instances.relationName();
		
		File xml = null;
		if(net != null && instances != null){
			if(instances != null){
				xml = openFile(ImageFilter.XML_EXTENSION);
				
				
				
//				xml = new File("C:/Documents and Settings/Ignacio/Escritorio/Eclipse/aa/DatosUsuario-107(ORDEN).xml");
				
//				try {
				stringArff = parse(xml);
//				} catch (Exception e) {
//				//TODO veer si agregamos algun cartel de error
//				e.printStackTrace();
			}
		}
		return stringArff;
		
	}
	//protected
	public Instances getRelations(File net) {
		BIFReader m_otherBayesNet = null;
		try {
			
			m_otherBayesNet = new BIFReader().processFile(net.getAbsolutePath());
			
		} catch (Throwable t) {            
			m_otherBayesNet = null;
			//TODO sacar este message
			System.out.print(t.getMessage());
		}
		if(m_otherBayesNet != null){
//			return m_otherBayesNet.m_Instances;
			Instances instances = new Instances(m_otherBayesNet.m_Instances);
			//agrega ? a cada atributo
			for (int i = 0; i < instances.numAttributes(); i++) {
				Attribute att = instances.attribute(i);			
				att.addNominalValue("?");
				
			}
			return instances;
			
		}
		return null;
		
		
		
	}
//	protected
	public Instances getRelations(String net) {
		BIFReader m_otherBayesNet = null;
		try {
			m_otherBayesNet = new BIFReader().processFile(net);
			
		} catch (Throwable t) {            
			m_otherBayesNet = null;
			//TODO sacar este message
			System.out.print(t.getMessage());
		}
		if(m_otherBayesNet != null){
//			return m_otherBayesNet.m_Instances;
			Instances instances = new Instances(m_otherBayesNet.m_Instances);
			//agrega ? a cada atributo
			for (int i = 0; i < instances.numAttributes(); i++) {
				Attribute att = instances.attribute(i);			
				att.addNominalValue("?");
				
			}
			return instances;
			
		}
		return null;
		
		
		
	}
	
	/**
	 * This method parses the string or the InputStream that we
	 * passed in through the constructor and builds up the
	 * m_nodes and m_edges vectors
	 * @exception - Exception if both the inString and inStream are
	 *              null, i.e. no input has been provided
	 * @exception - BIFFormatException if there is format of the
	 *              input is not correct. The format should conform to
	 *              XMLBIF version 0.3
	 * @exception - NumberFormatException if there is an invalid
	 *              char in the probability table of a node.
	 * @return    - returns the name of the graph
	 */
	public String parse(File file) throws Exception {
		String arff = instances.toString();
		InputStream inStream = new FileInputStream(file);
		Document dc=null;
		
		javax.xml.parsers.DocumentBuilderFactory dbf =
			javax.xml.parsers.DocumentBuilderFactory.newInstance();
		dbf.setIgnoringElementContentWhitespace(true);
		javax.xml.parsers.DocumentBuilder db = dbf.newDocumentBuilder();
		
		if(inStream!=null)
			dc = db.parse(inStream);
		else
		{ throw new Exception("No input given"); }
		
		int max = Integer.MIN_VALUE; 
		NodeList nl = dc.getElementsByTagName("NODE");    
		for(int i=0; i<nl.getLength(); i++) {
			System.out.println(((Element)nl.item(i)).getTextContent());
			System.out.println(((Element)nl.item(i)).getPrefix());
			NodeList list = ((Element)nl.item(i)).getElementsByTagName("DATA");
			if(list.getLength() > max){
				max = list.getLength();
			}
		}
		nl = dc.getElementsByTagName("NODE");    
		for(int i=0; i<max; i++) {
			String tupla = "";
			for(int j=0; j<nl.getLength(); j++) {
				System.out.println(((Element)nl.item(j)).getTextContent());
				NodeList nodeList = ((Element)nl.item(j)).getElementsByTagName("DATA");
				if(nodeList == null || nodeList.getLength() == 0){
					tupla += "?,";
				}else{
					if(nodeList.item(i) != null){
						tupla += nodeList.item(i).getFirstChild().getTextContent()+",";
					}else{
						tupla += "?,";
					}
					
				}
				System.out.println(tupla);
			}
			//Para sacrale la ultima coma
			tupla = tupla.substring(0,tupla.length()-1);
			arff = arff + tupla+"\n";
		}
		
		
		return normalize(arff);
	} 
	
	private String normalize(String arff){
		StringBuffer sStr2 = new StringBuffer();
		for (int iStr = 0; iStr < arff.length(); iStr++) {
			char c = arff.charAt(iStr);
			if(c == barra.charAt(0)){
				sStr2.append("");
			}else if(c == '%'){
				sStr2.append("");
			}
//			else if(c == aux.charAt(0)){
//			sStr2.append("");
//			}
			else{
				sStr2.append(c);
			}
		}
		return sStr2.toString();
	}
	
}
